<?php
/**
 * Created by PhpStorm.
 * User: 刘帅
 * Date: 2019-06-04
 * Time: 21:39
 */

namespace Extend\Drive\Cache;


class Redis
{
    private static $write_handle = null;
    private static $read_handle = null;

    /**
     * @写
     * @return \Redis|null
     */
    public static function getWrite()
    {
        $option = array(
            'host' => config('database.redis.default.host') ?? '127.0.0.1',
            'port' => config('database.redis.default.port') ?? 6379,
        );

        if (!self::$write_handle) {
            self::$write_handle = new \Redis();
            self::$write_handle->connect($option['host'], $option['port']);
        }

        return self::$write_handle;
    }

    /**
     * @读
     * @return \Redis|null
     */
    public static function getRead()
    {
        $option = array(
            'host' => config('database.redis.default.host') ?? '127.0.0.1',
            'port' => config('database.redis.default.port') ?? 6379,
        );

        if (!self::$read_handle) {
            self::$read_handle = new \Redis();
            self::$read_handle->connect($option['host'], $option['port']);
        }

        return self::$read_handle;
    }

    /**
     * 字符串赋值或者赋值并添加过期时间
     * @param $key
     * @param $value
     * @param int $expire
     * @return bool
     */
    public static function set($key, $value, $expire = 0)
    {
        if (!self::getWrite()) return false;
        if ($expire == 0) {
            return self::getWrite()->set($key, $value);
        } else {
            return self::getWrite()->setex($key, $expire, $value);
        }
    }

    /**
     * @字符串取值或者取数组
     * @param $key
     * @return mixed
     */
    public static function get($key)
    {
        $func = is_array($key) ? 'mget' : 'get';
        return self::getRead()->{$func}($key);
    }

    /**
     * @字符串递增数字或者增加指定的数字
     * @param $key
     * @param int $number
     * @return bool
     */
    public static function incr($key, $number = 1)
    {
        if (!self::getWrite()) return false;
        if ($number == 1) {
            return self::getWrite()->incr($key);
        } else {
            return self::getWrite()->incrBy($key, $number);
        }
    }

    /**
     * @字符串递减数字或者递减指定数字
     * @param $key
     * @param int $number
     * @return bool
     */
    public static function decr($key, $number = 1)
    {
        if (!self::getWrite()) return false;
        if ($number == 1) {
            return self::getWrite()->decr($key);
        } else {
            return self::getWrite()->decrBy($key, $number);
        }
    }

    /**
     * @字符串增加指定浮点数
     * @param $key
     * @param $float
     * @return bool|float
     */
    public static function incrByFloat($key, $float)
    {
        if (!self::getWrite()) return false;
        return self::getWrite()->incrByFloat($key, $float);
    }

    /**
     * @字符串向尾部追加值
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function append($key, $value)
    {
        if (!self::getWrite()) return false;
        return self::getWrite()->append($key, $value);
    }

    /**
     * @字符串获取长度
     * @param $key
     * @return bool|int
     */
    public static function strlen($key)
    {
        if (!self::getRead()) return false;
        return self::getRead()->strlen($key);
    }

    /**
     * @哈希赋值或者赋值多个字段
     * @param $key
     * @param $field
     * @param $value
     * @return bool|int
     */
    public static function hSet($key, $field, $value)
    {
        if (!self::getWrite()) return false;

        if (is_array($field)) {
            return self::getWrite()->hMSet($key, $field);
        } else {
            return self::getWrite()->hSet($key, $value, $value);
        }
    }

    /**
     * @哈希取值或者取得多个字段的值
     * @param $key
     * @param $field
     * @return array|bool|string
     */
    public static function hGet($key, $field)
    {
        if (!self::getRead()) return false;

        if (is_array($field)) {
            return self::getRead()->hMGet($key, $field);
        } else {
            return self::getRead()->hGet($key, $field);
        }
    }

    /**
     * @哈希取得所有字段的值
     * @param $key
     * @return array|bool
     */
    public static function hGetAll($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->hGetAll($key);
    }

    /**
     * @哈希获取字段的数量
     * @param $key
     * @return bool|int
     */
    public static function hLen($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->hLen($key);

    }

    /**
     * @哈希判断字段是否存在
     * @param $key
     * @param $field
     * @return bool
     */
    public static function hExists($key, $field)
    {
        if (!self::getRead()) return false;

        return self::getRead()->hExists($key, $field);
    }

    /**
     * @哈希当字段不存在时赋值
     * @param $key
     * @param $field
     * @param $value
     * @return bool
     */
    public static function hSetNx($key, $field, $value)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->hSetNx($key, $field, $value);
    }

    /**
     * @哈希增加数字
     * @param $key
     * @param $field
     * @param $num
     * @return bool|int
     */
    public static function hIncrBy($key, $field, $num = 1)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->hIncrBy($key, $field, $num);
    }

    /**
     * @哈希删除字段
     * @param $key
     * @param $field
     * @return bool|int
     */
    public static function hDel($key, $field)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->hDel($key, $field);
    }

    /**
     * @哈希获取所有字段名
     * @param $key
     * @return array|bool
     */
    public static function hKeys($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->hKeys($key);
    }

    /**
     * @哈希获取所有字段的值
     * @param $key
     * @return array|bool
     */
    public static function hVals($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->hVals($key);
    }

    /**
     * @列表向左端添加元素
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function lPush($key, $value)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->lPush($key, $value);
    }

    /**
     * @列表向右端添加元素
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function rPush($key, $value)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->rPush($key, $value);
    }

    /**
     * @列表从列表左端弹出元素
     * @param $key
     * @return bool|string
     */
    public static function lPop($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->lPop($key);
    }

    /**
     * @列表从列表右端弹出元素1
     * @param $key
     * @return bool|string
     */
    public static function rPop($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->rPop($key);
    }

    /**@列表获取列表中元素个数
     * @param $key
     * @return bool|int
     */
    public static function lSize($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->lSize($key);
    }

    /**
     * @列表获取列表中某一片的元素
     * @param $key
     * @param $start
     * @param $end
     * @return array|bool
     */
    public static function lRange($key, $start, $end)
    {
        if (!self::getRead()) return false;

        return self::getRead()->lRange($key, $start, $end);
    }

    /**@列表删除列表中指定的值
     * @param $key
     * @param $value
     * @param $count
     * @return bool|int
     */
    public static function lRem($key, $value, $count)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->lRem($key, $value, $count);
    }

    /**
     * @列表获取指定索引的元素值
     * @param $key
     * @param $index
     * @return bool|void
     */
    public static function lGet($key, $index)
    {
        if (!self::getRead()) return false;

        return self::getRead()->lGet($key, $index);
    }

    /**
     * @列表设置指定索引的元素值
     * @param $key
     * @param $index
     * @param $value
     * @return bool
     */
    public static function lSet($key, $index, $value)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->lSet($key, $index, $value);
    }

    /**
     * @列表只保留列表指定片段
     * @param $key
     * @param $start
     * @param $end
     * @return array|bool
     */
    public static function lTrim($key, $start, $end)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->lTrim($key, $start, $end);
    }

    /**
     * @无序集合添加元素
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function sAdd($key, $set)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->sAdd($key, $set);
    }

    /**
     * @无序集合删除元素
     * @param $key
     * @param $set
     * @return bool|int
     */
    public static function sRem($key, $set)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->sRem($key, $set);
    }

    /**
     * @无序集合获取集合中所有元素
     * @param $key
     * @return array|bool
     */
    public static function sMembers($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->sMembers($key);
    }

    /**
     * @无序集合判断元素是否在集合中
     * @param $key
     * @param $value
     * @return bool
     */
    public static function sIsMember($key, $value)
    {
        if (!self::getRead()) return false;

        return self::getRead()->sIsMember($key, $value);
    }

    /**
     * $无序集合对集合做差集运算
     * @param $key
     * @return bool|int
     */
    public static function sDiff($key)
    {
        if (!self::getRead()) return false;

        if (!is_array($key)) return false;

        $key = implode(',', $key);

        return self::getRead()->sDiffStore($key);
    }

    /**
     * @无序集合对集合做交集运算
     * @param $key
     * @return array|bool
     */
    public static function sInter($key)
    {
        if (!self::getRead()) return false;

        if (!is_array($key)) return false;

        $key = implode(',', $key);

        return self::getRead()->sInter($key);
    }

    /**
     * @无序集合对集合做并集运算
     * @param $key
     * @return array|bool
     */
    public static function sUnion($key)
    {
        if (!self::getRead()) return false;

        if (!is_array($key)) return false;

        $key = implode(',', $key);

        return self::getRead()->sUnion($key);
    }

    /**
     * @无序集合获取集合中元素的个数
     * @param $key
     * @return bool|int
     */
    public static function sCard($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->sCard($key);
    }

    /**
     * @无序集合对集合做差运算并将结果返回
     * @param $output
     * @param $key
     * @return array|bool
     */
    public static function sDiffStore($output, $key)
    {
        if (!self::getWrite()) return false;
        if (!self::getRead()) return false;

        if (!is_array($key)) ;
        return false;

        $key = implode(',', $key);

        self::getWrite()->sDiffStore($output, $key);

        return self::getRead()->sMembers($output);
    }

    /**
     * @无序集合对集合做交集运算并将结果返回
     * @param $output
     * @param $key
     * @return array|bool
     */
    public static function sInterStore($output, $key)
    {
        if (!self::getWrite()) return false;
        if (!self::getRead()) return false;

        if (!is_array($key)) ;
        return false;

        $key = implode(',', $key);

        self::getWrite()->sInterStore($output, $key);

        return self::getRead()->sMembers($output);
    }

    /**
     * @无序集合对集合做并集运算并将结果返回
     * @param $output
     * @param $key
     * @return array|bool
     */
    public static function sUnionStore($output, $key)
    {
        if (!self::getWrite()) return false;
        if (!self::getRead()) return false;

        if (!is_array($key)) ;
        return false;

        $key = implode(',', $key);

        self::getWrite()->sUnionStore($output, $key);

        return self::getRead()->sMembers($output);
    }

    /**@无序集合获取集合中的元素
     * @param $key
     * @param int $count
     * @return array|bool|string
     */
    public static function sRandMember($key, $count = 1)
    {
        if (!self::getRead()) return false;

        return self::getRead()->sRandMember($key, $count);
    }

    /**@无需集合随机弹出一个元素
     * @param $key
     * @return bool|string
     */
    public static function sPop($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->sPop($key);
    }

    /**
     * @有序集合添加元素
     * @param $key
     * @param $score
     * @param $value
     * @return bool|int
     */
    public static function zAdd($key, $score, $value)
    {
        if (!self::getWrite()) return false;

        return self::getRead()->zAdd($key, $score, $value);
    }

    /**
     * @有序集合获取元素分数
     * @param $key
     * @param $value
     * @return bool|float
     */
    public static function zScore($key, $value)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zScore($key, $value);
    }

    /**
     * @有序集合获取正序排名在某范围的元素
     * @param $key
     * @param $start
     * @param $stop
     * @return array|bool
     */
    public static function zRange($key, $start, $stop)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zRange($key, $start, $stop);
    }

    /**
     * @有序集合获取倒叙排名在某范围的元素
     * @param $key
     * @param $start
     * @param $stop
     * @return array|bool
     */
    public static function zRevRange($key, $start, $stop)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zRevRange($key, $start, $stop);
    }

    /**
     * @有序集合获取指定分数范围内的元素
     * @param $key
     * @param $start
     * @param $stop
     * @return array|bool
     */
    public static function zRangeByScore($key, $start, $stop)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zRangeByScore($key, $start, $stop);
    }

    /**
     * @有序集合增加某个元素的分数
     * @param $key
     * @param $increment
     * @param $member
     * @return array|bool
     */
    public static function zIncrBy($key, $increment, $member)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->zRangeByScore($key, $increment, $member);
    }

    /**
     * @有序集合获取集合中元素的个数
     * @param $key
     * @return bool|int
     */
    public static function zCard($key)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zCard($key);
    }

    /**
     * @有序集合获取指定分数范围内的元素个数
     * @param $key
     * @param $start
     * @param $end
     * @return bool|int
     */
    public static function zCount($key, $start, $end)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zCount($key, $start, $end);
    }

    /**
     * @有序集合删除元素
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function zDelete($key, $value)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->zDelete($key, $value);
    }

    /**
     * @有序集合按照排名范围删除元素
     * @param $key
     * @param $start
     * @param $stop
     * @return bool|int
     */
    public static function zRemRangeByRank($key, $start, $stop)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->zRemRangeByRank($key, $start, $stop);
    }

    /**
     * @有序集合按照分数范围删除元素
     * @param $key
     * @param $start
     * @param $stop
     * @return bool|int
     */
    public static function zRemRangeByScore($key, $start, $stop)
    {
        if (!self::getWrite()) return false;

        return self::getWrite()->zRemRangeByScore($key, $start, $stop);
    }

    /**
     * @有序集合获取正序排序的元素排名
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function zRank($key, $value)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zRank($key, $value);
    }

    /**
     * @有序集合获取逆序排序的元素排名
     * @param $key
     * @param $value
     * @return bool|int
     */
    public static function zRevRank($key, $value)
    {
        if (!self::getRead()) return false;

        return self::getRead()->zRevRank($key, $value);
    }
}